package it.bnl.layar.biz;

import it.bnl.layar.Response;
import it.bnl.layar.data.ActionData;
import it.bnl.layar.data.GetParameter;
import it.bnl.layar.data.Hotspot;
import it.bnl.layar.data.HotspotData;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;


public class RequestBiz {
	private static final Logger log = Logger.getLogger(RequestBiz.class
			.getName());

	private DataSource ds;
	private static final float kmDeg = 111.22625f;
	private static String layerName = "branchlocator";
	
	public RequestBiz() {
		try {
			Context ctx = new InitialContext();
			ds = (DataSource) ctx.lookup("java:comp/env/jdbc/dbBranchBNL");
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

	public Response handleRequest(GetParameter gp) {
		Response response = new Response();
		List<HotspotData> hotspots = null;
		
		String errore = "Nessun POI trovato. Aggiustare i parametri di ricerca.";
		
		// Get all the active hotspots within the specified radius
		hotspots = ricercaPuntuale(gp);
		
		if (hotspots!=null && hotspots.size() > 0) {
			response.setHotspots(createAllHotspots(hotspots, gp.getLatitudine(), gp.getLongitudine()));
			response.setErrorCode(0);
			response.setErrorString("ok");
			response.setLayer(layerName);
			response.setRefreshDistance(10); // 10 meters
			response.setRefreshInterval(3600); // 180 seconds
		} else {
			response.setErrorCode(20);
			response.setErrorString(errore);
			response.setLayer(layerName);
			response.setRefreshDistance(10); // 10 meters
			response.setRefreshInterval(3600); // 180 seconds
		}
		return response;
	}
		
	public List<HotspotData> ricercaPuntuale(GetParameter gp) {

		float delta[] = calculateDelta(gp.getRaggio() / 1000, gp.getLatitudine());
		float latmin = gp.getLatitudine()- delta[0];
		float latmax = gp.getLatitudine() + delta[0];
		float lonmin = gp.getLongitudine() - delta[1];
		float lonmax = gp.getLongitudine() + delta[1];
		List<HotspotData> hotspots = new ArrayList<HotspotData>();
		List<ActionData> ads = null;

		ResultSet resultSet = null;
		Connection connection = null;
		PreparedStatement ps = null;
		HotspotData hsd = null;
		ActionData ad = null;

		try {
			// Get Connection and Statement
			connection = ds.getConnection();

			String query = "SELECT * FROM Agenzia";
			ps = connection.prepareStatement(query);
			
			resultSet = ps.executeQuery();

			float lat = 0;
			float lon = 0;
			while (resultSet.next()) {
				lat = resultSet.getFloat("lat");
				lon = resultSet.getFloat("lon");
				if (lat >= latmin & lat <= latmax & lon >= lonmin & lon <= lonmax) {

					hsd = new HotspotData();
					hsd.setId(resultSet.getString("codAgenzia"));
					hsd.setLat(resultSet.getFloat("lat"));
					hsd.setLon(resultSet.getFloat("lon"));
					hsd.setTitle(resultSet.getString("codAgenzia"));
					hsd.setLine4(resultSet.getString("citta"));
					hsd.setLine3(resultSet.getString("indirizzo"));
					hsd.setLine2(resultSet.getString("provincia")+" - "+resultSet.getString("cap"));
					hsd.setImageURL("http://nomami.dlinkddns.com/BranchLocatorServices/content/BNL.gif");					
					
					ads = new ArrayList<ActionData>();

					ad = new ActionData();
					ad.setLabel("BNL Site");
					ad.setUri("http://m.bnl.it");
					ad.setContentType("text/html");
					ad.setActivityType(1);
					ads.add(ad);
					hsd.setActions(ads);
					hotspots.add(hsd);
				}
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {if (null != resultSet)resultSet.close();} catch (SQLException e1) {e1.printStackTrace();}
			try {if (null != ps) ps.close();} catch (SQLException e2) {e2.printStackTrace();}
			try {if (null != connection)connection.close();} catch (SQLException e3) {e3.printStackTrace();}
		}

		return hotspots;
	}

	private float[] calculateDelta(int radius, float lat) {
		float[] delta = new float[2];
		delta[0] = radius / kmDeg; // delta Lat
		delta[1] = radius / (float) (kmDeg * Math.cos(Math.toRadians(lat))); // delta
																				// Lon
		return delta;
	}

	public List<Hotspot> createAllHotspots(List<HotspotData> hotspots,
			float currLat, float currLon) {
		List<Hotspot> results = new ArrayList<Hotspot>();
		for (HotspotData hsd : hotspots) {
			results.add(hsd.createHotSpot(currLat, currLon));
		}
		return results;
	}
}
